home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 14552 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.7 KB

  1. Path: news.ucdavis.edu!quad!knight
  2. From: knight@quad.cs.ucdavis.edu (James Knight)
  3. Newsgroups: comp.lang.c,comp.unix.programmer
  4. Subject: Re: Q: '\n' character
  5. Followup-To: comp.lang.c,comp.unix.programmer
  6. Date: 15 Apr 1996 19:36:09 GMT
  7. Organization: University of California, Davis
  8. Message-ID: <4ku8f9$d3o@mark.ucdavis.edu>
  9. References: <4kj66f$k0o@ren.cei.net> <4kmdsv$ojc@masala.cc.uh.edu> <4kmhpsINN7ak@keats.ugrad.cs.ubc.ca> <AD97189A966891F2@mcdiala02.it.luc.edu> <4ktn04INNoev@keats.ugrad.cs.ubc.ca>
  10. NNTP-Posting-Host: quad.cs.ucdavis.edu
  11. X-Newsreader: TIN [version 1.2 PL2]
  12.  
  13. Kazimir Kylheku (c2a192@ugrad.cs.ubc.ca) wrote:
  14. : In article <AD97189A966891F2@mcdiala02.it.luc.edu>,
  15. : Verne Arase <VArase@varase.it.luc.edu> wrote:
  16. : >In article <4kmhpsINN7ak@keats.ugrad.cs.ubc.ca>,
  17. : >c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku) wrote:
  18. : >
  19. : >This is a failing of the C standard I/O library; fgets() _ought_ to have
  20. : >returned the length read.
  21.  
  22. : Yes it should. A lot of the standard I/O library is braindead, but it had to be
  23. : standardized a certain way to reflect existing practice and preserve the
  24. : correctness of existing programs.
  25.  
  26. : Or better still: how about returning a pointer to the last character read! This
  27. : would point to a null character if _no_ characters were read (thus indicating
  28. : EOF on the attempt to read the first character), or to either a newline or a
  29. : non-newline if at least one character was read. It would always be valid to
  30. : dereference the returned pointer, provided a valid buffer was passed in. A use
  31. : of fgets would then look like:
  32.  
  33.  
  34. I just bypass all of the problems with fgets using the function below.  It handles
  35. lines of any length, does the elimination of the newline, and the rest of my
  36. program doesn't have to worry about where to store the line.  Admittedly, it won't
  37. work for the original problem (for which Unix already has several solutions), but
  38. in the much more common case of reading a single file, or getting user input, this
  39. function makes the rest of the program much simpler.
  40.  
  41.  
  42.  
  43. /*
  44.  * my_getline
  45.  *
  46.  * Read a line of any length, store it in an internal buffer, and 
  47.  * return the internal buffer (along with a length value if desired).
  48.  *
  49.  * NOTE: Each line read will overwrite the previous line read.  So,
  50.  *       make a copy of any line you want to keep around.
  51.  *
  52.  * Parameters:
  53.  *     fp - A FILE pointer open for reading.
  54.  *     len_out - Address to where to store the line length.
  55.  *
  56.  * Returns:
  57.  *     An internal buffer containing the line, or NULL on EOF or error.
  58.  */
  59. char *my_getline(FILE *fp, int *len_out)
  60. {
  61.   static int bufsize = 0;
  62.   static char *buffer = NULL;
  63.   int size, len, flag;
  64.  
  65.   /*
  66.    * Initialize the internal buffer, if necessary.
  67.    */
  68.   if (buffer == NULL) {
  69.     bufsize = 128;
  70.     if ((buffer = malloc(bufsize)) == NULL)
  71.       return NULL;
  72.   }  
  73.  
  74.   /*
  75.    * Read the first part of the line.
  76.    */
  77.   flag = 0;
  78.   buffer[bufsize-2] = '\0';
  79.  
  80.   if (fgets(buffer, bufsize, fp) == NULL)
  81.     return NULL;
  82.   else if (buffer[bufsize-2] == '\0' || buffer[bufsize-2] == '\n') {
  83.     len = strlen(buffer);
  84.     flag = 1;
  85.   }
  86.  
  87.   /*
  88.    * If the line is longer, then realloc the internal buffer and
  89.    * read the next section of the line.
  90.    */
  91.   while (!flag) {
  92.     size = bufsize - 1;
  93.     bufsize += bufsize;
  94.     if ((buffer = realloc(buffer, bufsize)) == NULL)
  95.       return NULL;
  96.  
  97.     buffer[bufsize-2] = '\0';
  98.     if (fgets(buffer + size, bufsize - size, fp) == NULL) {
  99.       len = size;
  100.       flag = 1;
  101.     }
  102.     else if (!buffer[bufsize-2] || buffer[bufsize-2] == '\n') {
  103.       len = size + strlen(buffer + size);
  104.       flag = 1;
  105.     }
  106.   }
  107.  
  108.   /*
  109.    * Strip the newline from the line, if it's there.
  110.    */
  111.   if (buffer[len-1] == '\n')
  112.     buffer[--len] = '\0';
  113.  
  114.   if (len_out) *len_out = len;
  115.   return buffer;
  116. }
  117.  
  118.